﻿using FloorDesigner;
using OpenRPOSBackOffice.ServiceReferenceOpenRPOS;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Shapes;

namespace OpenRPOSBackOffice
{
    public partial class FloorLayout : UserControl, IDropContainer
    {
        bool _isMouseCaptured;
        private int _rowCount = 0;
        private int _columnCount = 0;
        public int _lastLayout = 0; // layout index value
        private string _droppedObjectParent = string.Empty; //  parent name of dropped table 
        private GeneralTransform _dragInitTransform = null;
        private bool _isOutfromContainer = false; 
        private bool _istableClicked = false;
        private int _selectedTable = -1;

        public FloorLayout()
        {
            InitializeComponent();
        }

        private void UserControl_Loaded(object sender, RoutedEventArgs e)
        {
            init();
            HorizontalRuler.AddLine();
            RulerVertical.AddLine();
        }

        private async void fillLayouts()
        {
            ddlLayout.Items.Clear();
            await Globals.db.GetTableLayoutObjects("1=1 order by Name"); //fetch records from database

            foreach (TableLayout tableLayout in Globals.db.TableLayoutRecords)
            {
                ddlLayout.Items.Add(new ComboBoxItem() { Tag = tableLayout.col_ID, Content = tableLayout.col_Name.Trim() });
            }

            if (ddlLayout.Items.Count > 0)
            {
                if (_lastLayout > 0) ddlLayout.SelectedValue = _lastLayout;
                else ddlLayout.SelectedIndex = 0;

                lblHeader.Content = string.Empty;
            }
            else
            {

                lblHeader.Content = string.Empty;
                ClearControls();
                ClearResizeAttachImage();
                LayoutContainer.Children.Clear();
                LayoutGrid.Children.Clear();
                LayoutGrid.Children.Add(LayoutContainer);
                //show popup to add first layout
                ShowLayoutUI(true);
            }
        }

        public void init()
        {
            Globals.showWaitCursor(true);
            var allowedSurfaces = new Panel[] { this.LayoutGrid };
            this.Ractangle.AllowedDropContainers = allowedSurfaces;
            this.Ellipse.AllowedDropContainers = allowedSurfaces;
            this.Ractangle.FloorDesigner.AllowedDropContainers = allowedSurfaces;
            this.Ellipse.FloorDesigner.AllowedDropContainers = allowedSurfaces;
            
            SetToolBoxControlInitialState();

            //populate layouts dropdown
            fillLayouts();
            Globals.floorLayout = this;
            Globals.showWaitCursor(false);
        }

        private void ToolBoxControl_MouseLeave(object sender, MouseEventArgs e)
        {
            TableControl oToolBoxControl = sender as TableControl;
            if (oToolBoxControl != null) if (oToolBoxControl.DragImage != null) oToolBoxControl.DragImage.Visibility = System.Windows.Visibility.Collapsed;
        }

        private void ToolBoxControl_MouseEnter(object sender, MouseEventArgs e)
        {
            TableControl oToolBoxControl = sender as TableControl;
            if (oToolBoxControl != null) if (oToolBoxControl.DragImage != null) oToolBoxControl.DragImage.Visibility = System.Windows.Visibility.Visible;
        }

        private void SetToolBoxControlInitialState()
        {
            UIElementCollection UICollection = gridToolBox.Children;
            foreach (TableControl ocontrol in UICollection)
            {
                ToolBoxControl_MouseLeave(ocontrol, null);
                ocontrol.MouseEnter += ToolBoxControl_MouseEnter;
                ocontrol.MouseLeave += ToolBoxControl_MouseLeave;
            }
        }

        #region Drag drop resize Events

        public void OnDropping(FrameworkElement droppingObject)
        {
            droppingObject.Margin = new Thickness(0.0d);
        }

        public void OnDropped(FrameworkElement droppedObject)
        {
            SetToolBoxControlInitialState();
            
            if (ddlLayout.SelectedItem == null)
            {
                MessageBox.Show("Please select layout name .");
                LayoutGrid.Children.Remove(droppedObject);
                return;
            }

            Globals.showWaitCursor(true);
            var droppedElement = (TableControl)droppedObject;
            if (droppedElement != null)
            {
                if (_droppedObjectParent == "gridToolBox" && string.IsNullOrWhiteSpace(Convert.ToString(droppedElement.Content)))
                {
                    FrameworkElement nearestTable;
                    if (IsTableExistsOnthisPosition(droppedObject, out nearestTable))
                        LayoutGrid.Children.Remove(droppedObject);
                    else
                    {
                        droppedElement.IsNew = true;
                        droppedElement.OnceCopy = false;
                        droppedElement.AllowCopy = false;
                        droppedElement.AllowedDropContainers = new Panel[] { LayoutGrid };
                        Grid.SetRowSpan(droppedElement, _rowCount);
                        Grid.SetColumnSpan(droppedElement, _columnCount);
                        
                        ClearControls();
                        ClearResizeAttachImage();
                        AddTable(droppedElement);
                        ResizeHandle.SetAttach(droppedObject, true);
                        //if (LayoutContainer.Children.Contains(ResizeHandle._popups[droppedObject]) == false)
                        //{
                        //    LayoutContainer.Children.Add(ResizeHandle._popups[droppedObject]);
                        //}
                        //ResizeHandle._popups[droppedObject].Child.Visibility = System.Windows.Visibility.Visible; //set image for selected table 
                    }
                }
                else
                {
                    double xPoint = 0;
                    double yPoint = 0;
                    GetXYPoint(out xPoint, out yPoint);

                    if (yPoint < 0 || xPoint < 0 || yPoint + droppedObject.Height >= LayoutGrid.Height || xPoint + droppedObject.Width >= LayoutGrid.Width)
                    {
                        _isOutfromContainer = true;
                    }
                    Handle_MouseUp(droppedObject, null);
                }
            }
            Globals.showWaitCursor(false);
        }

        private void GetXYPoint(out double xpoint, out double ypoint)
        {
            xpoint = 0;
            ypoint = 0;
            Label lPoint = LayoutContainer.FindName("XYPoint") as Label;
            if (lPoint != null)
            {
                xpoint = Math.Round(Convert.ToDouble(lPoint.GetValue(Canvas.LeftProperty)) - 5, 2);
                ypoint = Math.Round(Convert.ToDouble(lPoint.GetValue(Canvas.TopProperty)) + 15, 2);
            }
        }

        private bool IsTableExistsOnthisPosition(FrameworkElement droppedObject, out FrameworkElement NearestTable)
        {
            UIElementCollection collection = LayoutContainer.Children;

            GeneralTransform gt = droppedObject.TransformToVisual(LayoutGrid);
            Point offset = gt.Transform(new Point(0, 0));
            double xPoint = offset.X;
            double YPoint = offset.Y;

            foreach (FrameworkElement element in collection)
            {
                if (Convert.ToInt32(droppedObject.Tag) == Convert.ToInt32(element.Tag) || element.Tag == null)
                {
                    continue;
                }

                gt = element.TransformToVisual(LayoutGrid);
                offset = gt.Transform(new Point(0, 0));
                if (doOverlap(new Point(xPoint, YPoint), new Point(xPoint + droppedObject.Width, YPoint + droppedObject.Height), offset,
                     new Point(offset.X + element.Width, offset.Y + element.Height)))
                {
                    NearestTable = element;
                    return true;
                }
            }

            collection = LayoutGrid.Children;
            foreach (FrameworkElement element in collection)
            {
                if (Convert.ToInt32(droppedObject.Tag) == Convert.ToInt32(element.Tag) || element.Tag == null)
                {
                    continue;
                }

                gt = element.TransformToVisual(LayoutGrid);
                offset = gt.Transform(new Point(0, 0));

                if (doOverlap(new Point(xPoint, YPoint), new Point(xPoint + droppedObject.Width, YPoint + droppedObject.Height), offset,
                     new Point(offset.X + element.Width, offset.Y + element.Height)))
                {
                    NearestTable = element;
                    return true;
                }
            }

            NearestTable = null;
            return false;
        }

        // Returns true if two rectangles (l1, r1) and (l2, r2) overlap
        bool doOverlap(Point l1, Point r1, Point l2, Point r2)
        {
            if (l1.X < r2.X && r1.X > l2.X && l1.Y < r2.Y && r1.Y > l2.Y) return true;

            return false;

        }

        public void OnDragStart(FrameworkElement draggedObject)
        {
            var droppedElement = (TableControl)draggedObject;
            if (droppedElement != null && ddlLayout.SelectedItem != null)
            {
                _droppedObjectParent = Convert.ToString(droppedElement.Parent.GetValue(FrameworkElement.NameProperty)); //set name of drop parent
            }
        }

        public void OnDragMouseOver(FrameworkElement draggedObject)
        {
            //Debug.WriteLine("OnDragMouseOver");
        }

        public void OnElementContainerEnter(FrameworkElement enterObject)
        {
            //Debug.WriteLine("OnElementContainerEnter");
        }

        public void OnElementContainerExit(FrameworkElement leaveObject)
        {
            _isOutfromContainer = true;
            //Debug.WriteLine("OnElementContainerExit");
        }

        public void Handle_MouseDown(object sender, MouseEventArgs args)
        {
            //Debug.WriteLine("Handle_MouseDown");
            FrameworkElement item = sender as FrameworkElement;
           
            _isMouseCaptured = true;
            _istableClicked = true;

            ClearResizeAttachImage(); //clear  resize image

            SetPropertyControlEnableDisable(true);
            
            if (item != null)
            {
                item.CaptureMouse();
                txtTableNumber.Text = Convert.ToString(((TableControl)item).Content);
                txtTableNumber.Tag = item.Tag;
                SetFocusOnTable((TableControl)item);
                _selectedTable = -1;
                txtWidth.Text = string.Format("{0:0.00}", item.Width);
                txtHeight.Text = string.Format("{0:0.00}", item.Height);
                chkRactangle.IsChecked = ((TableControl)item).IsRactangle;
                _dragInitTransform = ((TableControl)item).TransformToVisual(LayoutGrid);

                Point offset = _dragInitTransform.Transform(new Point(0, 0));
                txtclientY.Text = string.Format("{0:0.00}", offset.Y);
                txtclientX.Text = string.Format("{0:0.00}", offset.X);
                ResizeHandle._popups[item].SetValue(Canvas.TopProperty, Convert.ToDouble(offset.Y));
                ResizeHandle._popups[item].SetValue(Canvas.LeftProperty, Convert.ToDouble(offset.X));

            }
        }

        public void Handle_MouseMove(object sender, MouseEventArgs args)
        {
            try
            {
                FrameworkElement item = sender as FrameworkElement;
                if (_isMouseCaptured)
                {
                    if (item != null)
                    {
                        GeneralTransform gt = item.TransformToVisual(LayoutGrid);
                        Point offset = gt.Transform(new Point(0, 0));
                        ResizeHandle._popups[item].SetValue(Canvas.TopProperty, Convert.ToDouble(offset.Y));
                        ResizeHandle._popups[item].SetValue(Canvas.LeftProperty, Convert.ToDouble(offset.X));

                        btnHorizontal.SetValue(Canvas.LeftProperty, offset.X - 10);
                        btnVertical.SetValue(Canvas.TopProperty, offset.Y + 5);

                        ShowFocusLine("XAxisLine", true, 0, offset.Y, offset.X, offset.Y);
                        ShowFocusLine("YAxisLine", true, offset.X, 0, offset.X, offset.Y);
                    }
                }
            }
            catch(Exception ex)
            {
                //log Exception 
            }
        }

        private void SetReSizeImageLocation(FrameworkElement item)
        {
            if (item != null)
            {
                ResizeHandle._popups[item].SetValue(Canvas.TopProperty, Convert.ToDouble(item.GetValue(Canvas.TopProperty)));
                ResizeHandle._popups[item].SetValue(Canvas.LeftProperty, Convert.ToDouble(item.GetValue(Canvas.LeftProperty)));
            }
        }

        public void Handle_MouseUp(object sender, MouseEventArgs args)
        {
            try
            {
                _isMouseCaptured = false;
                FrameworkElement item = sender as FrameworkElement;
                if (item != null)
                {
                    item.ReleaseMouseCapture();
                    GeneralTransform gt = null;
                    var droppedElement = (TableControl)item;
                    if (droppedElement != null)
                    {
                        FrameworkElement nearestTable;
                        if (_isOutfromContainer || IsTableExistsOnthisPosition(item, out nearestTable))
                        {
                            if (_dragInitTransform != null) gt = _dragInitTransform;

                            _isOutfromContainer = false;
                        }
                    }

                    if (gt == null)
                    {
                        gt = item.TransformToVisual(LayoutGrid);
                    }

                    Point offset = gt.Transform(new Point(0, 0));
                    // check  if these points are out of container 
                    if (offset.Y < 0 || offset.X < 0 || offset.Y + item.Height >= LayoutGrid.Height || offset.X + item.Width >= LayoutGrid.Width)
                    {
                        if (_dragInitTransform != null) gt = _dragInitTransform;
                        if (gt == null)
                        {
                            gt = item.TransformToVisual(LayoutGrid);
                        }

                        offset = gt.Transform(new Point(0, 0));

                    }

                    ClearControls();
                    _istableClicked = true;
                    _selectedTable = Convert.ToInt32(item.Tag);
                    txtclientY.Text = string.Format("{0:0.00}", offset.Y + 0.00000001);
                    txtclientX.Text = string.Format("{0:0.00}", offset.X + 0.00000001);

                    txtTableNumber.Text = Convert.ToString(((TableControl)item).Content);
                    txtWidth.Text = string.Format("{0:0.00}", item.Width);
                    txtHeight.Text = string.Format("{0:0.00}", item.Height);
                    UpdateTableDetails(item);
                    //Set focus on table
                    SetFocusOnTable((TableControl)item);
                    txtTableNumber.Focus();
                }
            }
            catch (Exception ex)
            {
                // log Exception
            }
        }

        public void Handle_SizeChanged(object sender, SizeChangedEventArgs e)
        {
            Globals.showWaitCursor(true);
            FrameworkElement element = sender as FrameworkElement;
            if (element != null && txtTableNumber.Tag != null)
            {

                double height = element.Height;
                double width = element.Width;

                double xPoint = 0;
                double yPoint = 0;
                GetXYPoint(out xPoint, out yPoint);

                if (yPoint < 0 || xPoint < 0 || yPoint + height >= LayoutGrid.Height || xPoint + width >= LayoutGrid.Width)
                {
                    _isOutfromContainer = true;
                }

                GeneralTransform gt= null;
                FrameworkElement nearestTable = null;
                if (_isOutfromContainer  || IsTableExistsOnthisPosition(element, out nearestTable))
                {
                    if (_dragInitTransform != null) gt = _dragInitTransform; // set initial position of table if table overlap or out of Container 

                    _isOutfromContainer = false;
                }

                if (gt == null)
                {
                    gt = element.TransformToVisual(LayoutGrid);
                }

                Point offset = gt.Transform(new Point(0, 0));

                if (nearestTable != null)
                {
                    ClearResizeAttachImage(true);
                    if (_istableClicked == false)
                    {
                        if (e.NewSize.Height - e.PreviousSize.Height > 0) height = height - 5;
                        if (e.NewSize.Width - e.PreviousSize.Width > 0) width = width - 5;
                    }

                }

                if ((offset.Y + element.Height) > LayoutGrid.Height)
                {
                    ClearResizeAttachImage(true);
                    height = LayoutGrid.Height - offset.Y;
                }

                if ((offset.X + element.Width) > LayoutGrid.Width)
                {
                    ClearResizeAttachImage(true);
                    width = LayoutGrid.Width - offset.X;
                }
               
                txtWidth.Text = string.Format("{0:0.00}", width);
                txtHeight.Text = string.Format("{0:0.00}", height);
                UpdateTableDetails(element);
                
            }

            Globals.showWaitCursor(false);
        }

        private void Handle_MouseLeave(object sender, MouseEventArgs e)
        {
            _istableClicked = false;
        }
        
        private void Handle_MouseEnter(object sender, MouseEventArgs args)
        {
            try
            {
                FrameworkElement item = sender as FrameworkElement;
                

                //check if table is already selected 
                if (txtTableNumber.Tag != null)
                {
                    return;
                }

                //clear  resize image 
                ClearResizeAttachImage();
                _isMouseCaptured = false;
                if (item != null)
                {
                    GeneralTransform gt = null;
                    gt = item.TransformToVisual(LayoutGrid);
                    Point offset = gt.Transform(new Point(0, 0));
                    txtclientY.Text = string.Format("{0:0.00}", offset.Y);
                    txtclientX.Text = string.Format("{0:0.00}", offset.X);
                    txtTableNumber.Text = Convert.ToString(((TableControl)item).Content);
                    txtWidth.Text = string.Format("{0:0.00}", item.Width);
                    txtHeight.Text = string.Format("{0:0.00}", item.Height);
                    SetFocusOnTable((TableControl)item);
                    txtTableNumber.Tag = null;
                    _selectedTable = -1;
                    ClearResizeAttachImage(true);
                    btnHorizontal.SetValue(Canvas.LeftProperty, offset.X - 10);
                    btnVertical.SetValue(Canvas.TopProperty, offset.Y + 5);
                    ResizeHandle._popups[item].SetValue(Canvas.TopProperty, Convert.ToDouble(offset.Y));
                    ResizeHandle._popups[item].SetValue(Canvas.LeftProperty, Convert.ToDouble(offset.X));

                    ShowFocusLine("XAxisLine", true, 0, offset.Y, offset.X, offset.Y);
                    ShowFocusLine("YAxisLine", true, offset.X, 0, offset.X, offset.Y);
                    txtTableNumber.Focus();
                }
            }
            catch (Exception ex)
            {
                // log exception 
            }
        }

        /// <summary>
        /// Create a line for measurement Focus 
        /// </summary>
        private  void CreateFocusLine(string name, bool isFirstTime = false)
        {
            try
            {
                // Create a Line
                Line redLine = new Line();
                redLine.Name = name;
                redLine.X1 = 50;
                redLine.Y1 = 50;
                redLine.X2 = 200;
                redLine.Y2 = 200;
                // Create a red Brush
                SolidColorBrush redBrush = new SolidColorBrush();
                redBrush.Color = Colors.Red;
                // Set Line's width and color
                redLine.StrokeThickness = 2;
                redLine.Stroke = redBrush;
                Grid.SetRowSpan(redLine, _rowCount);
                Grid.SetColumnSpan(redLine, _columnCount);
                redLine.SetValue(Canvas.ZIndexProperty, 0);
                // Add line to the Grid.
                redLine.Visibility = System.Windows.Visibility.Collapsed;
                LayoutGrid.Children.Add(redLine);

                if (isFirstTime)
                {
                    // create XY point of table 
                    Label lPoint = new Label() { Name = "XYPoint", Visibility = System.Windows.Visibility.Collapsed  };
                    Grid.SetRowSpan(lPoint, _rowCount);
                    Grid.SetColumnSpan(lPoint, _columnCount);
                    lPoint.Style = this.Resources["XYPoint"] as Style;
                    LayoutContainer.Children.Add(lPoint);
                }
            }
            catch (Exception ex)
            {

            }

        }

        private void ShowFocusLine(string name, bool isvisible, double X1,  double Y1,  double X2,  double Y2)
        {
            Line myline = LayoutGrid.FindName(name) as Line;
            if (myline != null)
            {
                myline.X1 = X1;
                myline.Y1 = Y1;
                myline.X2 = X2;
                myline.Y2 = Y2;
                myline.Visibility = (isvisible == true ? System.Windows.Visibility.Visible : System.Windows.Visibility.Collapsed);
                myline.SetValue(Canvas.ZIndexProperty, 0);
            }

            Label lPoint = LayoutContainer.FindName("XYPoint") as Label;
            if (lPoint != null)
            {
                lPoint.Content = "(" +Convert.ToInt32(X2) + "," + Convert.ToInt32(Y2) + ")";
                lPoint.SetValue(Canvas.TopProperty, Y2-15);
                lPoint.SetValue(Canvas.LeftProperty, X2+5);
                lPoint.Visibility = (isvisible == true ? System.Windows.Visibility.Visible : System.Windows.Visibility.Collapsed);
               
                lPoint.SetValue(Canvas.ZIndexProperty, 0);
            }


        }
        
        #endregion

        #region Table creation

        /// <summary>
        /// Add new table on layout 
        /// </summary>
        /// <param name="item"></param>
        private async void AddTable(TableControl item)
        {
            if (ddlLayout.SelectedItem == null)
            {
                MessageBox.Show("Please select layout name .");
                return;
            }

            try
            {
                GeneralTransform gt = item.TransformToVisual(LayoutGrid);
                Point offset = gt.Transform(new Point(0, 0));

                await Globals.db.GetTableSpecificationObjects("");

                int maxID = 0;
                if (Globals.db.TableSpecificationRecords.Count > 0) maxID = Globals.db.TableSpecificationRecords.Max<TableSpecification>(s => s.col_TableNumber);

                TableSpecification oTableSpecification = new TableSpecification()
                {
                    bFilterCapacity = true,
                    bFilterCenterX = true,
                    bFilterCenterY = true,
                    bFilterLength = true,
                    bFilterOccupied = true,
                    bFilterRectangle = true,
                    bFilterRotation = true,
                    bFilterTableLayoutID = true,
                    bFilterTableNumber = true,
                    bFilterWidth = true,
                    col_Capacity = 1,
                    col_CenterX = Convert.ToDouble(offset.X),
                    col_CenterY = Convert.ToDouble(offset.Y),
                    col_Length = Convert.ToDouble(item.Width),
                    col_Occupied = false,
                    col_Rectangle = Convert.ToBoolean(item.IsRactangle),
                    col_Rotation = 1,
                    col_TableLayoutID = Convert.ToInt32(ddlLayout.SelectedValue),
                    col_TableNumber = maxID + 1,
                    col_Width = Convert.ToDouble(item.Height)
                };

                await Globals.db.AddTableSpecificationObject(oTableSpecification);

                await Globals.db.GetTableSpecificationObjects("TableNumber=" + Convert.ToInt32(oTableSpecification.col_TableNumber));
                item.Content = oTableSpecification.col_TableNumber;
                item.IsNew = true;
                item.IsRactangle = Convert.ToBoolean(item.IsRactangle);
                if (Globals.db.TableSpecificationRecords.Count > 0)
                {
                    item.Name = Convert.ToString(Globals.db.TableSpecificationRecords[0].col_ID);
                    item.Content = Globals.db.TableSpecificationRecords[0].col_TableNumber;
                    item.Tag = Globals.db.TableSpecificationRecords[0].col_ID;
                    txtTableNumber.Tag = item.Tag;
                    _selectedTable = Convert.ToInt32(item.Tag);
                    txtTableNumber.Text = Convert.ToString(item.Content);
                    txtWidth.Text = string.Format("{0:0.00}", item.Width);
                    txtHeight.Text = string.Format("{0:0.00}", item.Height);
                    chkRactangle.IsChecked = item.IsRactangle;
                    item.Foreground = new SolidColorBrush(Colors.Blue);
                    item.BorderBrush = new SolidColorBrush(Colors.Blue);
                    txtclientY.Text = string.Format("{0:0.00}", offset.Y);
                    txtclientX.Text = string.Format("{0:0.00}", offset.X);
                    item.MouseLeftButtonDown += Handle_MouseDown;
                    item.SizeChanged += Handle_SizeChanged;
                    item.MouseLeave += Handle_MouseLeave;
                    item.MouseMove += Handle_MouseMove;
                    item.MouseEnter += Handle_MouseEnter;

                    RadialGradientBrush fiveColorRGB = new RadialGradientBrush();
                    GradientStop blueGS = new GradientStop();
                    GradientStop orangeGS = new GradientStop();

                    if (item.IsRactangle)
                    {
                        item.Style = this.Resources["RectangleStyle"] as Style;
                        blueGS.Color = Colors.Blue;
                        orangeGS.Color = Colors.Blue;
                        blueGS.Offset = 1;
                        orangeGS.Offset = 1;
                    }
                    else
                    {
                        item.Style = this.Resources["EllipseStyle"] as Style;
                        blueGS.Color = Colors.Blue;
                        orangeGS.Color = Colors.Transparent;
                        blueGS.Offset = 1;
                        orangeGS.Offset = 1;
                    }

                    fiveColorRGB.GradientStops.Add(blueGS);
                    fiveColorRGB.GradientStops.Add(orangeGS);
                    item.Background = fiveColorRGB;
                    SetFocusOnTable(item);
                }
            }
            catch (Exception ex)
            {
                // log exception
            }
        }

        private async void CreateTable(int layoutID)
        {
            await Globals.db.GetTableSpecificationObjects("TableLayoutID=" + layoutID + " order by TableNumber");

            if (Globals.db.TableSpecificationRecords.Count > 0)
            {
                foreach (TableSpecification oTableSpecification in Globals.db.TableSpecificationRecords)
                {
                    CreateCanvas(Convert.ToString(oTableSpecification.col_TableNumber), Convert.ToString(oTableSpecification.col_ID), (oTableSpecification.col_Rectangle ? Globals.TableType.Ractangle : Globals.TableType.Ellipse)
                    , oTableSpecification.col_Length, oTableSpecification.col_Width, oTableSpecification.col_CenterY, oTableSpecification.col_CenterX, oTableSpecification.col_Occupied);
                }       
            }
        }

        private void CreateCanvas(string canvasName, string canvasID, Globals.TableType tableShapeType, double width, double height, double top, double left, bool isOccupied)
        {
            try
            {
                TableControl controlCanvas = new TableControl();
                controlCanvas.Name = canvasID;
                controlCanvas.Tag = canvasID;
                controlCanvas.IsRactangle = (tableShapeType == Globals.TableType.Ractangle ? true : false);

                controlCanvas.Width = width;
                controlCanvas.Height = height;

                controlCanvas.Foreground = new SolidColorBrush(Colors.Blue);
                controlCanvas.BorderBrush = new SolidColorBrush(Colors.Blue);
                controlCanvas.Content = canvasName;
                controlCanvas.MouseLeftButtonDown += Handle_MouseDown;
                controlCanvas.MouseLeave += Handle_MouseLeave;
                controlCanvas.SizeChanged += Handle_SizeChanged;
                controlCanvas.MouseMove += Handle_MouseMove;
                controlCanvas.MouseEnter += Handle_MouseEnter;
                Grid.SetRowSpan(controlCanvas, _rowCount);
                Grid.SetColumnSpan(controlCanvas, _columnCount);

                controlCanvas.AllowedDropContainers = new Panel[] { LayoutGrid };
                controlCanvas.VerticalAlignment = System.Windows.VerticalAlignment.Bottom;

                controlCanvas.BorderThickness = new Thickness(2.0);
                controlCanvas.Padding = new Thickness(2.0);
                controlCanvas.SetValue(Canvas.LeftProperty, left);
                controlCanvas.SetValue(Canvas.TopProperty, top);

                RadialGradientBrush fiveColorRGB = new RadialGradientBrush();
                GradientStop blueGS = new GradientStop();
                GradientStop orangeGS = new GradientStop();

                switch (tableShapeType)
                {
                    case Globals.TableType.Ellipse:
                        controlCanvas.Style = this.Resources["EllipseStyle"] as Style;
                        blueGS.Color = Colors.Blue;
                        orangeGS.Color = Colors.Transparent;

                        blueGS.Offset = 1;
                        orangeGS.Offset = 1;
                        break;

                    case Globals.TableType.Ractangle:
                        controlCanvas.Style = this.Resources["RectangleStyle"] as Style;
                        blueGS.Color = Colors.Blue;
                        orangeGS.Color = Colors.Blue;
                        blueGS.Offset = 1;
                        orangeGS.Offset = 1;
                        break;
                }

                fiveColorRGB.GradientStops.Add(blueGS);
                fiveColorRGB.GradientStops.Add(orangeGS);
                
                controlCanvas.Background = fiveColorRGB;
                controlCanvas.IsNew = false;
                controlCanvas.DragImageVisibility = false;
                controlCanvas.TableNoVisibility = false;
                controlCanvas.IsOccupied = isOccupied;
                var myElement = (LayoutContainer.Children.SingleOrDefault<UIElement>(label => Convert.ToString(label.GetValue(FrameworkElement.NameProperty)) == Convert.ToString(controlCanvas.Tag)));

                if (myElement == null)
                {
                    LayoutContainer.Children.Add(controlCanvas);
                    ResizeHandle.SetAttach(controlCanvas, true);
                    if (LayoutContainer.Children.Contains(ResizeHandle._popups[controlCanvas]) == false)
                    {
                        LayoutContainer.Children.Add(ResizeHandle._popups[controlCanvas]);                       
                    }
                    ResizeHandle._popups[controlCanvas].Child.Visibility = System.Windows.Visibility.Collapsed; //set image for selected table 
                }
            }
            catch (Exception ex)
            {
                //log exception 
            }
        }

        private void SetFocusOnTable(TableControl controlCanvas)
        {
            SetPropertyControlEnableDisable(true);
            
            txtTableNumber.Tag = controlCanvas.Tag;
            _selectedTable = Convert.ToInt32(controlCanvas.Tag);
            
            FrameworkElement element = controlCanvas as FrameworkElement;

            ResizeHandle.SetAttach(element, true);
            if (LayoutContainer.Children.Contains(ResizeHandle._popups[controlCanvas]) == false)
            {
                LayoutContainer.Children.Add(ResizeHandle._popups[controlCanvas]);
            }
            ResizeHandle._popups[element].Child.Visibility = System.Windows.Visibility.Visible; //set image for selected table 
            Thumb oThumb = ((Thumb)ResizeHandle._popups[element].Child) as Thumb;
            if (oThumb != null)
            {
                oThumb.Style = this.Resources["MyThumbStyle"] as Style;
            }
                     
            if (controlCanvas.IsRactangle == false) 
            {
                RadialGradientBrush fiveColorRGB = new RadialGradientBrush();
                GradientStop blueGS = new GradientStop();
                GradientStop orangeGS = new GradientStop();
                GradientStop blackGS = new GradientStop();

                blueGS.Color = Colors.Blue;
                orangeGS.Color = Colors.Transparent;
                blackGS.Color = Colors.White;
                blueGS.Offset = .85;
                blackGS.Offset = 1;
                orangeGS.Offset = 1;

                fiveColorRGB.GradientStops.Add(blueGS);
                fiveColorRGB.GradientStops.Add(blackGS);
                fiveColorRGB.GradientStops.Add(orangeGS);
                controlCanvas.Background = fiveColorRGB;
            }
            (controlCanvas).BorderThickness = new Thickness(4);
            (controlCanvas).BorderBrush = new SolidColorBrush(Colors.White);
            if (controlCanvas.DragImage != null) controlCanvas.DragImage.Visibility = System.Windows.Visibility.Visible;
            txtTableNumber.Focus();
        }

        private async void UpdateTableDetails(FrameworkElement item)
        {
            try
            {
                if (item.Tag != null && txtTableNumber.Tag != null)
                {
                    await Globals.db.GetTableSpecificationObjects("ID=" + Convert.ToInt32(item.Tag));
                    if (Globals.db.TableSpecificationRecords.Count > 0)
                    {
                        foreach (TableSpecification oTableSpecification in Globals.db.TableSpecificationRecords)
                        {
                            oTableSpecification.bFilterCapacity = true;
                            oTableSpecification.bFilterCenterX = true;
                            oTableSpecification.bFilterCenterY = true;
                            oTableSpecification.bFilterLength = true;
                            oTableSpecification.bFilterOccupied = true;
                            oTableSpecification.bFilterRectangle = true;
                            oTableSpecification.bFilterRotation = true;
                            oTableSpecification.bFilterTableLayoutID = true;
                            oTableSpecification.bFilterTableNumber = true;
                            oTableSpecification.bFilterWidth = true;

                            oTableSpecification.col_TableNumber = Convert.ToInt32(((TableControl)item).Content);
                            oTableSpecification.col_Length = item.Width;
                            oTableSpecification.col_Width = item.Height;

                            GeneralTransform gt = item.TransformToVisual(LayoutGrid);
                            Point offset = gt.Transform(new Point(0, 0));

                            oTableSpecification.col_CenterX = offset.X;
                            oTableSpecification.col_CenterY = offset.Y;

                            //oTableSpecification.col_Rectangle = ((TableControl)item).IsRactangle;
                            int x = await Globals.db.UpdateTableSpecificationObject(oTableSpecification);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                //log exception 
            }
        }

        private async void UpdateTableDetails(object itemID)
        {
            try
            {
                if (itemID != null)
                {
                    await Globals.db.GetTableSpecificationObjects("ID=" + Convert.ToInt32(itemID));
                    if (Globals.db.TableSpecificationRecords.Count > 0)
                    {
                        foreach (TableSpecification oTableSpecification in Globals.db.TableSpecificationRecords)
                        {
                            oTableSpecification.bFilterCapacity = true;
                            oTableSpecification.bFilterCenterX = true;
                            oTableSpecification.bFilterCenterY = true;
                            oTableSpecification.bFilterLength = true;
                            oTableSpecification.bFilterOccupied = true;
                            oTableSpecification.bFilterRectangle = true;
                            oTableSpecification.bFilterRotation = true;
                            oTableSpecification.bFilterTableLayoutID = true;
                            oTableSpecification.bFilterTableNumber = true;
                            oTableSpecification.bFilterWidth = true;

                            oTableSpecification.col_TableNumber = Convert.ToInt32(txtTableNumber.Text.Trim() == "" ? "1.0" : txtTableNumber.Text.Trim());
                            oTableSpecification.col_Length = Convert.ToDouble(txtWidth.Text.Trim() == "" ? "1.0" : txtWidth.Text.Trim());
                            oTableSpecification.col_Width = Convert.ToDouble(txtHeight.Text.Trim() == "" ? "1.0" : txtHeight.Text.Trim());
                            oTableSpecification.col_CenterX = Convert.ToDouble(txtclientX.Text.Trim() == "" ? "1.0" : txtclientX.Text.Trim());
                            oTableSpecification.col_CenterY = Convert.ToDouble(txtclientY.Text.Trim() == "" ? "1.0" : txtclientY.Text.Trim());

                            //oTableSpecification.col_Rectangle = Convert.ToBoolean(chkRactangle.IsChecked);
                            int x = await Globals.db.UpdateTableSpecificationObject(oTableSpecification);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                //log exception 
            }
        }

        private async void RemoveTableDetails(FrameworkElement item)
        {
            ClearResizeAttachImage();
            try
            {
                await Globals.db.GetTableSpecificationObjects("ID=" + Convert.ToInt32(item.Tag));

                if (Globals.db.TableSpecificationRecords.Count > 0)
                {
                    foreach (TableSpecification oTableSpecification in Globals.db.TableSpecificationRecords)
                    {
                        await Globals.db.DeleteTableSpecificationObject(oTableSpecification);
                    }
                }
            }
            catch (Exception ex)
            {
                // log exception 
            }
            ClearControls();
        }

        #endregion

        #region Page  Control Events

        private void addtableLayout_Click(object sender, RoutedEventArgs e)
        {
            ShowLayoutUI(true);
        }

        private void btnEdittableLayout_Click(object sender, RoutedEventArgs e)
        {
            ShowLayoutUI(false);
        }

        private void ShowLayoutUI(bool isNew = false)
        {
            ClearResizeAttachImage();
            int iLayoutId = -1;
            if (!isNew)
            {
                if (ddlLayout.SelectedItem == null)
                {
                    MessageBox.Show("Please select layout name .");
                    return;
                }

                iLayoutId = Convert.ToInt32(ddlLayout.SelectedValue);
            }

            AddLayout layoutWnd = new AddLayout();
            if (iLayoutId > 0) layoutWnd.Title = "Edit Layout";
            layoutWnd._layoutID = iLayoutId;
            layoutWnd.Closed += new EventHandler(loginWnd_Closed);
            layoutWnd.Show();
        }

        private async void btnDeletetableLayout_Click(object sender, RoutedEventArgs e)
        {
            if (ddlLayout.SelectedItem == null)
            {
                MessageBox.Show("Please select layout name .");
                return;
            }

            if (MessageBox.Show("Are you sure you want to delete layout and it's table(s) ?", "Confirm", MessageBoxButton.OKCancel) == MessageBoxResult.OK)
            {
                Globals.showWaitCursor(true);
                int iLayoutId = Convert.ToInt32(ddlLayout.SelectedValue);
                await Globals.db.GetTableLayoutObjects("ID=" + iLayoutId);

                if (Globals.db.TableLayoutRecords.Count > 0)
                {

                    await Globals.db.GetTableSpecificationObjects("TableLayoutID=" + iLayoutId);
                    foreach (TableSpecification otables in Globals.db.TableSpecificationRecords)
                    {
                        await Globals.db.DeleteTableSpecificationObject(otables);
                    }

                    await Globals.db.DeleteTableLayoutObject(Globals.db.TableLayoutRecords[0]);
                }

                Globals.showWaitCursor(false);
                _lastLayout = 0;
                init();
            }
        }

        private void loginWnd_Closed(object sender, EventArgs e)
        {
            AddLayout oAddLayout = (AddLayout)sender;

            if (oAddLayout.DialogResult == true && string.IsNullOrWhiteSpace(oAddLayout.txtLayoutName.Text) == false)
            {
                _lastLayout = oAddLayout._layoutID;
                lblHeader.Content = oAddLayout.txtLayoutName.Text.Trim() + " (Width : " + oAddLayout.txtWidth.Text + ", height : " + oAddLayout.txtHeight.Text + ")";
                init();
            }
        }

        private UIElement GetElementByName()
        {
            if ((txtTableNumber.Tag == null) ||
                (txtTableNumber.Tag != null && string.IsNullOrWhiteSpace(Convert.ToString(txtTableNumber.Tag))))
            {
                return null;
            }

            // find table element in container
            var element =  (LayoutGrid.Children.SingleOrDefault<UIElement>(label => Convert.ToString(label.GetValue(FrameworkElement.NameProperty)) == Convert.ToString(txtTableNumber.Tag)));
            if (element == null)
            {
                element = (LayoutContainer.Children.SingleOrDefault<UIElement>(label => Convert.ToString(label.GetValue(FrameworkElement.NameProperty)) == Convert.ToString(txtTableNumber.Tag)));
            }
            return element;
        }

        /// <summary>
        /// Remove table from layout 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Thumb_Click(object sender, RoutedEventArgs e)
        {

            // find table element in container
            var myElement = GetElementByName();
            if (myElement == null)
            {
                return;
            }

            TableControl oTable = myElement as TableControl;
            if (oTable != null)
            {
                if (oTable.IsOccupied)
                {
                    MessageBox.Show("Table is already reserved.");
                    return;
                }
            }

            MessageBoxResult result = MessageBox.Show("Are you want to remove table .", " Confirm ", MessageBoxButton.OKCancel);

            if (result == MessageBoxResult.OK)
            {
                FrameworkElement item = myElement as FrameworkElement;
                if (item != null)
                {
                    //remove table 
                    RemoveTableDetails(item);
                }

                LayoutContainer.Children.Remove(myElement);
                LayoutGrid.Children.Remove(myElement);
            }
        }

        private void txtLength_TextChanged(object sender, TextChangedEventArgs e)
        {
            try
            {
                Debug.WriteLine("txtwidth_TextChanged");
                // find table element in container
                var myElement = GetElementByName();
                if (myElement == null)
                {
                    return;
                }

                FrameworkElement item = myElement as FrameworkElement;
                double width = Convert.ToDouble(txtWidth.Text == "" ? "0.0" : txtWidth.Text);
                double positionX = Convert.ToDouble(txtclientX.Text == "" ? "0.0" : txtclientX.Text);

                if (item != null)
                {
                    if ((positionX + width) > LayoutGrid.Width)
                    {
                        item.Width = Convert.ToDouble((LayoutGrid.Width - positionX));
                    }
                    else
                    {
                        item.Width = Convert.ToDouble(width);
                    }
                }
            }
            catch (Exception ex)
            {
                //log exception
            }
        }

        private void txtLength_KeyDown(object sender, KeyEventArgs e)
        {
            try
            {
                DecimalExtensions.SetDecimalTextBox(sender, e);
                if (Convert.ToDouble(((TextBox)e.OriginalSource).Text) > (LayoutGrid.Width - Convert.ToDouble(txtclientX.Text)))
                {
                    e.Handled = true;
                }
            }
            catch (Exception ex)
            {
            }
        }

        private void txtwidth_TextChanged(object sender, TextChangedEventArgs e)
        {
            try
            {
                Debug.WriteLine("txtwidth_TextChanged");
                // find table element in container
                var myElement = GetElementByName();
                if (myElement == null)
                {
                    return;
                }

                FrameworkElement item = myElement as FrameworkElement;

                double height = Convert.ToDouble(txtHeight.Text == "" ? "0.0" : txtHeight.Text);
                double positionY = Convert.ToDouble(txtclientY.Text == "" ? "0.0" : txtclientY.Text);

                if (item != null)
                {
                    if ((positionY + height) > LayoutGrid.Height)
                    {
                        item.Height = Convert.ToDouble((LayoutGrid.Height - positionY));
                    }
                    else
                    {
                        item.Height = Convert.ToDouble(height);
                    }
                }
            }
            catch (Exception ex)
            {
                //log exception 
            }
        }

        private void txtwidth_KeyDown(object sender, KeyEventArgs e)
        {
            try
            {
                DecimalExtensions.SetDecimalTextBox(sender, e);
                if (Convert.ToDouble(((TextBox)e.OriginalSource).Text) > (LayoutGrid.Height - Convert.ToDouble(txtclientY.Text)))
                {
                    e.Handled = true;
                }
            }
            catch (Exception ex)
            {
            }
        }

        private void txtclientX_KeyDown(object sender, KeyEventArgs e)
        {
            try
            {
                DecimalExtensions.SetDecimalTextBox(sender, e);
                if (Convert.ToDouble(((TextBox)e.OriginalSource).Text) > (LayoutGrid.Width - Convert.ToDouble(txtWidth.Text)))
                {
                    e.Handled = true;
                }
            }
            catch (Exception ex)
            {
            }
        }

        private void txtclientY_KeyDown(object sender, KeyEventArgs e)
        {
            try
            {
                DecimalExtensions.SetDecimalTextBox(sender, e);
                if (Convert.ToDouble(((TextBox)e.OriginalSource).Text) > (LayoutGrid.Height - Convert.ToDouble(txtHeight.Text)))
                {
                    e.Handled = true;
                }
            
            }
            catch (Exception ex)
            {
            }
        }

        /// <summary>
        /// Render item according to ClientX , ClientY property text box 
        /// </summary>
        private void SetItemPosition(bool isDragPositionUpdate = false)
        {
            // find table element in container
            var myElement = GetElementByName();

            if (myElement == null)
            {
                return;
            }

            FrameworkElement item = myElement as FrameworkElement;

            double pointX = 0;
            double pointY = 0;

            pointX = (string.IsNullOrWhiteSpace(txtclientX.Text) == true ? 0 : Convert.ToDouble(txtclientX.Text));
            pointY = (string.IsNullOrWhiteSpace(txtclientY.Text) == true ? 0 : Convert.ToDouble(txtclientY.Text));

            btnHorizontal.SetValue(Canvas.LeftProperty, pointX-10);
            btnVertical.SetValue(Canvas.TopProperty, pointY+5);

            ShowFocusLine("XAxisLine", true, 0, pointY, pointX, pointY);
            ShowFocusLine("YAxisLine", true, pointX, 0, pointX, pointY);


            if (item != null)
            {
                if ((_selectedTable != -1 && isDragPositionUpdate == false) || ((TableControl)item).IsNew)
                {
                    Debug.WriteLine("RenderTransform");
                        var transform = ((TableControl)item).FloorDesigner.CombineTransformations(
                                        new Point(pointX + item.Width / 2.0, pointY + item.Height / 2.0),
                                        null,
                                        1.0,
                                        1.0);

                        item.RenderTransform = transform;
                }
                else
                {
                    Debug.WriteLine("NOT- RenderTransform");
                    item.SetValue(Canvas.TopProperty, pointY);
                    item.SetValue(Canvas.LeftProperty, pointX);
                }

                ResizeHandle._popups[item].SetValue(Canvas.TopProperty, pointY);
                ResizeHandle._popups[item].SetValue(Canvas.LeftProperty, pointX);
                
                if (isDragPositionUpdate)
                {
                    _dragInitTransform = item.TransformToVisual(LayoutGrid);
                }
            }
        }

        private void txtclientX_TextChanged(object sender, TextChangedEventArgs e)
        {
            SetItemPosition();
        }

        private void txtclientY_TextChanged(object sender, TextChangedEventArgs e)
        {
            SetItemPosition();
        }

        private async void ddlLayout_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            Globals.showWaitCursor(true);
            if (((ComboBox)sender).SelectedItem != null)
            {
                await Globals.db.GetTableLayoutObjects("ID=" + Convert.ToInt32(((ComboBox)sender).SelectedValue));
                if (Globals.db.TableLayoutRecords.Count > 0)
                {
                    lblHeader.Content = Globals.db.TableLayoutRecords[0].col_Name + " (Width : " + Globals.db.TableLayoutRecords[0].col_Length + ", Height : " + Globals.db.TableLayoutRecords[0].col_Width + ")";
                    LayoutContainer.Children.Clear();
                    ClearResizeAttachImage();
                    LayoutGrid.Children.Clear();
                    LayoutGrid.RowDefinitions.Clear();
                    LayoutGrid.ColumnDefinitions.Clear();


                    _rowCount = (int)(Globals.db.TableLayoutRecords[0].col_Width / 50);
                    _columnCount = (int)(Globals.db.TableLayoutRecords[0].col_Length / 50);

                    for (int i = 0; i < _rowCount; i++)
                    {
                        RowDefinition rd = new RowDefinition();
                        rd.Height = new GridLength(50);
                        LayoutGrid.RowDefinitions.Add(rd);
                    }

                    for (int i = 0; i < _columnCount; i++)
                    {
                        ColumnDefinition cd = new ColumnDefinition();
                        cd.Width = new GridLength(50);
                        LayoutGrid.ColumnDefinitions.Add(cd);
                    }


                    LayoutContainer.Width = Globals.db.TableLayoutRecords[0].col_Length;
                    LayoutContainer.Height = Globals.db.TableLayoutRecords[0].col_Width;
                    LayoutGrid.Width = Globals.db.TableLayoutRecords[0].col_Length;
                    LayoutGrid.Height = Globals.db.TableLayoutRecords[0].col_Width;
                    
                    LayoutRulerHorizontal.Width = Globals.db.TableLayoutRecords[0].col_Length;
                    CanvasHorizontal.Width = Globals.db.TableLayoutRecords[0].col_Length;
                    HorizontalRuler.Width = Globals.db.TableLayoutRecords[0].col_Length;
                    HorizontalRuler.SetWidth(HorizontalRuler.Width); 
                    ScrollGrid.Width = Globals.db.TableLayoutRecords[0].col_Length + 40;
                    ScrollGrid.ColumnDefinitions[1].MaxWidth = Globals.db.TableLayoutRecords[0].col_Length + 40;

                    LayoutRulerVertical.Height = Globals.db.TableLayoutRecords[0].col_Width;
                    canvasVertical.Height = Globals.db.TableLayoutRecords[0].col_Width;
                    RulerVertical.Height = Globals.db.TableLayoutRecords[0].col_Width;
                    RulerVertical.SetWidth(RulerVertical.Height);
                    ScrollGrid.Height = Globals.db.TableLayoutRecords[0].col_Width + 40;
                    ScrollGrid.RowDefinitions[1].MaxHeight = Globals.db.TableLayoutRecords[0].col_Width + 40;
                    CreateFocusLine("XAxisLine", true);
                    CreateFocusLine("YAxisLine");

                    LayoutContainer.HorizontalAlignment = System.Windows.HorizontalAlignment.Left;
                    LayoutContainer.VerticalAlignment = System.Windows.VerticalAlignment.Top;
                    
                    LayoutGrid.Children.Add(LayoutContainer);
                    if (_columnCount > 0 && _rowCount > 0)
                    {
                        Grid.SetColumnSpan(LayoutContainer, _columnCount);
                        Grid.SetRowSpan(LayoutContainer, _rowCount);
                        CreateTable(Globals.db.TableLayoutRecords[0].col_ID);
                    }
                }
            }

            ClearControls();
            Globals.showWaitCursor(false);
            

        }

        private void SetPropertyControlEnableDisable(bool isvisible)
        {
            txtclientX.IsEnabled = isvisible;
            txtclientY.IsEnabled = isvisible;
            txtWidth.IsEnabled = isvisible;
            txtHeight.IsEnabled = isvisible;
            txtTableNumber.IsEnabled = isvisible;
            txtRotation.IsEnabled = isvisible;
        }

        /// <summary>
        /// Clear value of input controls
        /// </summary>
        private void ClearControls()
        {
            txtTableNumber.Tag = null;
            _selectedTable = -1;
            txtclientX.Text = string.Empty;
            txtclientY.Text = string.Empty;
            txtWidth.Text = string.Empty;
            txtHeight.Text = string.Empty;
            txtTableNumber.Text = string.Empty;
            txtRotation.Text = string.Empty;

            SetPropertyControlEnableDisable(false);
            
            chkRactangle.IsChecked = false;
            chkRactangle.IsEnabled = false;
           
            _isMouseCaptured = false;
            _istableClicked = false;

            btnHorizontal.SetValue(Canvas.LeftProperty, 0.0);
            btnVertical.SetValue(Canvas.TopProperty, 0.0);

            ShowFocusLine("XAxisLine", false, 0, 0, 0, 0);
            ShowFocusLine("YAxisLine", false, 0, 0, 0, 0);

        }

        /// <summary>
        /// clear resize image 
        /// </summary>
        private void ClearResizeAttachImage(bool isfromResize = false)
        {
            foreach (KeyValuePair<FrameworkElement, Popup> oControl in ResizeHandle._popups)
            {
                if (isfromResize == false)
                {
                    TableControl oTable = oControl.Key as TableControl;
                    if (oTable != null)
                    {
                        oTable.BorderThickness = new Thickness(2);
                        oTable.BorderBrush = new SolidColorBrush(Colors.Blue);

                        if (oTable.IsRactangle == false)
                        {
                            RadialGradientBrush fiveColorRGB = new RadialGradientBrush();
                            GradientStop blueGS = new GradientStop();
                            GradientStop orangeGS = new GradientStop();

                            blueGS.Color = Colors.Blue;
                            orangeGS.Color = Colors.Transparent;
                            blueGS.Offset = 1;
                            orangeGS.Offset = 1;


                            fiveColorRGB.GradientStops.Add(blueGS);
                            fiveColorRGB.GradientStops.Add(orangeGS);

                            oTable.Background = fiveColorRGB;
                            
                        }

                        if (oTable.DragImage != null) oTable.DragImage.Visibility = System.Windows.Visibility.Collapsed;
                    }
                }

                var childElement = oControl.Value.Child as FrameworkElement;
                childElement.Visibility = System.Windows.Visibility.Collapsed;
            }
        }


        private void txtWidth_KeyUp(object sender, KeyEventArgs e)
        {
            try
            {

                // find table element in container
                var myElement = GetElementByName();

                if (myElement == null)
                {
                    return;
                }

                FrameworkElement item = myElement as FrameworkElement;
                FrameworkElement oNearestElement;
                GeneralTransform gt = item.TransformToVisual(LayoutGrid);
                if (IsTableExistsOnthisPosition(item, out oNearestElement))
                {
                    gt = oNearestElement.TransformToVisual(LayoutGrid);
                }

                Point offset = gt.Transform(new Point(0, 0));

                TextBox txtbox = ((TextBox)e.OriginalSource);
                if (txtbox != null)
                {
                    double width = Convert.ToDouble(txtbox.Text == "" ? "0.0" : txtbox.Text);
                    double positionX = Convert.ToDouble(txtclientX.Text == "" ? "0.0" : txtclientX.Text);

                    if (oNearestElement != null)
                    {
                        Point offsetNearTable = _dragInitTransform.Transform(new Point(0, 0));
                        width = (offsetNearTable.X > offset.X ? offsetNearTable.X - offset.X : offset.X - offsetNearTable.X) - 5;
                    }

                    if ((positionX + width) > LayoutGrid.Width)
                    {
                        e.Handled = true;
                        txtWidth.Text = string.Format("{0:0.00}", (LayoutGrid.Width - positionX));
                    }
                    else
                    {
                        txtWidth.Text = string.Format("{0:0.00}", width);
                    }

                    UpdateTableDetails(txtTableNumber.Tag);
                }
            }
            catch (Exception ex)
            {
                // log exception
            }
        }

        private void txtHeight_KeyUp(object sender, KeyEventArgs e)
        {
            try
            {
                // find table element in container
                var myElement = GetElementByName();

                if (myElement == null)
                {
                    return;
                }

                FrameworkElement item = myElement as FrameworkElement;
                FrameworkElement oNearestElement;
                GeneralTransform gt = item.TransformToVisual(LayoutGrid);
                if (IsTableExistsOnthisPosition(item, out oNearestElement))
                {
                    gt = oNearestElement.TransformToVisual(LayoutGrid);
                }

                Point offset = gt.Transform(new Point(0, 0));

                TextBox txtbox = ((TextBox)e.OriginalSource);
                if (txtbox != null)
                {
                    double height = Convert.ToDouble(txtbox.Text == "" ? "0.0" : txtbox.Text);
                    double positionY = Convert.ToDouble(txtclientY.Text == "" ? "0.0" : txtclientY.Text);
                    if (oNearestElement != null)
                    {
                        Point offsetNearTable = _dragInitTransform.Transform(new Point(0, 0));
                        height = (offsetNearTable.Y > offset.Y ? offsetNearTable.Y - offset.Y : offset.Y - offsetNearTable.Y) - 5;
                    }

                    if ((positionY + height) > LayoutGrid.Height)
                    {
                        e.Handled = true;
                        txtHeight.Text = string.Format("{0:0.00}", (LayoutGrid.Height - positionY));
                    }
                    else
                    {
                        txtHeight.Text = string.Format("{0:0.00}", height);
                    }
                    UpdateTableDetails(txtTableNumber.Tag);
                }
            }
            catch (Exception ex)
            {
                // log exception
            }
        }

        private void SetPositionOnKeyup(bool isXAxisPoint, KeyEventArgs e)
        {
            // find table element in container
            var myElement = GetElementByName();

            if (myElement == null)
            {
                return;
            }

            TextBox txtbox = ((TextBox)e.OriginalSource);
            if (txtbox != null)
            {
                double positionX = (isXAxisPoint ? Convert.ToDouble(txtbox.Text == "" ? "0.0" : txtbox.Text) : Convert.ToDouble(txtclientX.Text == "" ? "0.0" : txtclientX.Text));
                double width = Convert.ToDouble(txtWidth.Text == "" ? "0.0" : txtWidth.Text);
                double positionY = (isXAxisPoint == false ? Convert.ToDouble(txtbox.Text == "" ? "0.0" : txtbox.Text) : Convert.ToDouble(txtclientY.Text == "" ? "0.0" : txtclientY.Text));
                double height = Convert.ToDouble(txtHeight.Text == "" ? "0.0" : txtHeight.Text);


                if (isXAxisPoint && (positionX > (LayoutGrid.Width - width)))
                {
                    _isOutfromContainer = true;
                }
                else if (isXAxisPoint == false && (positionY > (LayoutGrid.Height - height)))
                {
                    _isOutfromContainer = true;
                }


                FrameworkElement item = myElement as FrameworkElement;
                FrameworkElement oNearestElement = null;
                GeneralTransform gt = item.TransformToVisual(LayoutGrid);
                if (_isOutfromContainer || IsTableExistsOnthisPosition(item, out oNearestElement))
                {
                    if (_dragInitTransform != null) gt = _dragInitTransform;
                }

                if (gt == null)
                {
                    gt = item.TransformToVisual(LayoutGrid);
                }

                Point offset = gt.Transform(new Point(0, 0));

                if (oNearestElement != null || _isOutfromContainer)
                {
                    if (isXAxisPoint) positionX = offset.X;
                    else positionY = offset.Y;

                    //_dragInitTransform = gt;
                }

               // _selectedTable = Convert.ToInt32(txtTableNumber.Tag);
                if (isXAxisPoint) txtclientX.Text = string.Format("{0:0.00}", positionX + 0.00000001);
                else txtclientY.Text = string.Format("{0:0.00}", positionY + 0.00000001);


                SetItemPosition(true);
                UpdateTableDetails(txtTableNumber.Tag);

            }

        }
        
        private void txtclientX_KeyUp(object sender, KeyEventArgs e)
        {
            try
            {
                SetPositionOnKeyup(true, e);
            }
            catch (Exception ex)
            {
                // log exception
            }

            _isOutfromContainer = false;

        }

        private void txtclientY_KeyUp(object sender, KeyEventArgs e)
        {
            try
            {
                SetPositionOnKeyup(false, e);
            }
            catch (Exception ex)
            {
                // log exception
            }

            _isOutfromContainer = false;
        }

        private void LayoutGrid_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            try
            {
                if (_isMouseCaptured == false || _istableClicked== false)
                {
                    ClearControls();
                    ClearResizeAttachImage();
                    ShowFocusLine("XAxisLine", false, 0, 0, 0, 0);
                    ShowFocusLine("YAxisLine", false, 0, 0, 0,0);
                }
            }
            catch (Exception ex)
            {
                // log exception
            }

        }

        private void UserControl_Unloaded(object sender, RoutedEventArgs e)
        {
            ClearResizeAttachImage();
            ShowFocusLine("XAxisLine", false, 0, 0, 0, 0);
            ShowFocusLine("YAxisLine", false, 0, 0, 0, 0);
        }

        private void txtTableNumber_KeyDown(object sender, KeyEventArgs e)
        {
            try
            {
                DecimalExtensions.SetNumberTextBox(sender, e);                
            }
            catch (Exception ex)
            {
            }
        }

        private void txtTableNumber_KeyUp(object sender, KeyEventArgs e)
        {
            try
            {
                TextBox txtbox = ((TextBox)e.OriginalSource);
                if (txtbox != null)
                {
                    UpdateTableDetails(txtTableNumber.Tag);
                }
            }
            catch (Exception ex)
            {
                // log exception
            }
        }

        private void txtTableNumber_TextChanged(object sender, TextChangedEventArgs e)
        {
            // find table element in container
            var myElement = GetElementByName();
            if (myElement == null)
            {
                return;
            }

            FrameworkElement item = myElement as FrameworkElement;
            if (item != null)
            {
                ((TableControl)item).Content = txtTableNumber.Text;
            }
        }

        #endregion

        private void btnPreviewLayout_Click(object sender, RoutedEventArgs e)
        {

            if (ddlLayout.SelectedItem == null)
            {
                MessageBox.Show("Please select layout name .");
                return;
            }

            ChildWindow wndLayoutPreview = new ChildWindow();
            wndLayoutPreview.Title = "Preview Layout";
            wndLayoutPreview.Margin = new Thickness(2);
            LayoutViewer oLayoutViewer = new LayoutViewer();
            oLayoutViewer._lastLayout = Convert.ToInt32(ddlLayout.SelectedValue);
            wndLayoutPreview.Content = oLayoutViewer;
            wndLayoutPreview.Show();
        }
        
        private void Image_ImageFailed(object sender, ExceptionRoutedEventArgs e)
        {
            
        }

        double lastVerticalOffset;
        double lastHorizontalOffset;
        private void ScrollViewer_MouseMove(object sender, MouseEventArgs e)
        {
            double verticalOffset = ((ScrollViewer)sender).VerticalOffset;
            double horizontalOffset = ((ScrollViewer)sender).HorizontalOffset;
           
            if (verticalOffset != lastVerticalOffset || horizontalOffset != lastHorizontalOffset)
            {
                ScrollChangedEventArgs args = new ScrollChangedEventArgs();
                args.HorizontalChange = horizontalOffset - lastHorizontalOffset;
                args.HorizontalOffset = horizontalOffset;
                args.VerticalChange = verticalOffset - lastVerticalOffset;
                args.VerticalOffset = verticalOffset;
                ScrollChanged(args);
                lastHorizontalOffset = horizontalOffset;
                lastVerticalOffset = verticalOffset;
            }
        }

        private void ScrollChanged(ScrollChangedEventArgs e)
        {
            string str = e.VerticalOffset + "," + e.HorizontalOffset;

            // find table element in container
            var myElement = GetElementByName();
            if (myElement == null)
            {
                return;
            }

            FrameworkElement item = myElement as FrameworkElement;
            if (item != null)
            {
                double xAxis = Convert.ToDouble(item.GetValue(Canvas.LeftProperty));
                double yAxis = Convert.ToDouble(item.GetValue(Canvas.TopProperty));

                if (xAxis > 0 && yAxis > 0)
                {
                    ResizeHandle._popups[item].SetValue(Canvas.TopProperty, yAxis);
                    ResizeHandle._popups[item].SetValue(Canvas.LeftProperty, xAxis);
                }

                ResizeHandle._popups[item].Visibility = System.Windows.Visibility.Visible;
                if (e.VerticalOffset > 0 || e.HorizontalOffset > 0)
                {

                    if (xAxis + item.Width + 30 < e.HorizontalOffset || yAxis + item.Height + 30 < e.VerticalOffset)
                        ResizeHandle._popups[item].Visibility = System.Windows.Visibility.Collapsed;
                }
            }
        }

        private class ScrollChangedEventArgs
        {

            public double HorizontalOffset { get; set; }
            public double VerticalOffset { get; set; }
            public double HorizontalChange { get; set; }
            public double VerticalChange { get; set; }
        }


    }
}
